﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BLL;
using System.Runtime.InteropServices;
using Model;

namespace UtilityHelper
{
    public class CameraInfo
    {
        private Int32[] m_lUserID = new Int32[5];
        public Int32[] m_lAlarmHandle = new Int32[200];
        private Int32 iListenHandle = -1;
        private int iDeviceNumber = 0; //添加设备个数
        private uint iLastErr = 0;
        private string strErr;
        private CHCNetSDK.MSGCallBack m_falarmData = null;
        private Flecks m_fleck;
        private CAMERA_INFO m_UserInfo;
        public Dictionary<int, bool> AlarmResult = new Dictionary<int, bool>();

        public Dictionary<int, bool> InitCamera = new Dictionary<int,bool>();


        CHCNetSDK.NET_VCA_TRAVERSE_PLANE m_struTraversePlane = new CHCNetSDK.NET_VCA_TRAVERSE_PLANE();
        CHCNetSDK.NET_VCA_AREA m_struVcaArea = new CHCNetSDK.NET_VCA_AREA();
        CHCNetSDK.NET_VCA_INTRUSION m_struIntrusion = new CHCNetSDK.NET_VCA_INTRUSION();
        CHCNetSDK.UNION_STATFRAME m_struStatFrame = new CHCNetSDK.UNION_STATFRAME();
        CHCNetSDK.UNION_STATTIME m_struStatTime = new CHCNetSDK.UNION_STATTIME();

        private static volatile CameraInfo instance = null;

        private static object lockHelper = new object();

        /// <summary>
        /// SDK初始化是否成功
        /// </summary>
        public bool bInit { get; set; }

        /// <summary>
        /// 摄像头初始化是否成功
        /// </summary>
        public bool bInitCamera = false;

        public Dictionary<int, bool> dicUserReg { get; set; }

        public List<int> LineNums { get; set; }

        private CameraInfo() { }

        public static CameraInfo GetInstance(int lineNum)
        {
            lock (lockHelper)
            {
                if (instance == null)
                {
                    instance = new CameraInfo();
                    instance.bInit = CHCNetSDK.NET_DVR_Init();
                    CAMERA_INFO_BLL bll = new CAMERA_INFO_BLL();
                    instance.m_UserInfo = bll.GetModel(1);

                    for (int i = 0; i < 5;i++ )
                    {
                       instance.m_lAlarmHandle[i] = -1;
                       instance.m_lUserID[i] = -1;
                    }

                    instance.LineNums = new List<int>();
                    instance.LineNums.Add(lineNum);
                    instance.dicUserReg = new Dictionary<int, bool>();
                    //instance.dicUserReg.Add(lineNum,instance.UserRegister(lineNum));
                    instance.UserRegister(lineNum);
                    instance.SetAlert(lineNum);
                }
                else
                {
                    if (!instance.LineNums.Contains(lineNum))
                    {
                        //instance.dicUserReg.Add(lineNum, instance.UserRegister(lineNum));
                        instance.LineNums.Add(lineNum);
                        instance.UserRegister(lineNum);
                        instance.SetAlert(lineNum);
                    }
                }

                //设置报警回调函数
                instance.m_falarmData = new CHCNetSDK.MSGCallBack(instance.MsgCallback);
                CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V30(instance.m_falarmData, IntPtr.Zero);

                return instance;
            }
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public Dictionary<int, bool> UserRegister(int lineNum)
        {
            bInitCamera = false;
            CAMERA_INFO_BLL bll = new CAMERA_INFO_BLL();
            var Infos = bll.GetModelList("IsEnabled='True' and LineNum='" + lineNum + "'");

            CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
            for (int i = 0; i < Infos.Length; i++)
            {
                m_lUserID[lineNum] = CHCNetSDK.NET_DVR_Login_V30(Infos[i].CameraIP, Convert.ToInt32(Infos[i].CameraPort), m_UserInfo.UserName, m_UserInfo.UserPwd, ref DeviceInfo);
            }

            if (Infos.Length == 0)
            {

                m_lUserID[lineNum] = -1;
            }

            if (m_lUserID[lineNum] > -1)
            {
                bInitCamera = true;
            }


            if (InitCamera.Keys.Contains(lineNum))
            {
                InitCamera[lineNum] = bInitCamera;
            }
            else
            {
                InitCamera.Add(lineNum, bInitCamera);
            }

            return InitCamera;
        }

        public bool SetAlert(int lineNum)
        {
            CHCNetSDK.NET_DVR_SETUPALARM_PARAM struAlarmParam = new CHCNetSDK.NET_DVR_SETUPALARM_PARAM();
            struAlarmParam.dwSize = (uint)Marshal.SizeOf(struAlarmParam);
            struAlarmParam.byLevel = 1; //0- 一级布防,1- 二级布防
            struAlarmParam.byAlarmInfoType = 1;//智能交通设备有效，新报警信息类型
            bool succ = true;

            if (AlarmResult.Keys.Contains(lineNum) && AlarmResult[lineNum])
            {
                return succ;
            }

            if (m_lUserID[lineNum] > -1 )
            {
                m_lAlarmHandle[lineNum] = CHCNetSDK.NET_DVR_SetupAlarmChan_V41(m_lUserID[lineNum], ref struAlarmParam);

                if (m_lAlarmHandle[lineNum] < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    succ = false;
                }
                if (AlarmResult.Keys.Contains(lineNum))
                {
                    AlarmResult[lineNum] = succ;
                }
                else
                {
                    AlarmResult.Add(lineNum, succ);
                }
                return succ;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 撤销布防
        /// </summary>
        /// <param name="lineNum">安检线号</param>
        /// <returns>true/false</returns>
        public bool CloseAlert(int lineNum)
        {
            bool succ = false;
            if (m_lUserID[lineNum] >= 0)
            {
                succ = CHCNetSDK.NET_DVR_CloseAlarmChan_V30(instance.m_lAlarmHandle[lineNum]);
                if (succ)
                {
                    AlarmResult[lineNum] = false;
                }
            }
            return succ;
        }

        /// <summary>
        /// 释放SDK资源
        /// </summary>
        /// <returns></returns>
        public bool CleanUp()
        {
            for (int i = 1; i < 5; i++)
            {
                CloseAlert(i);
            }
            for (int j = 0; j < m_lUserID.Length; j++)
            {
                m_lUserID[j] = -1;
            }

            int[] keys = InitCamera.Keys.ToArray();

            for (int i = 0; i < keys.Length; i++)
            {
                InitCamera[keys[i]] = false;
            }

            bool succ = CHCNetSDK.NET_DVR_Cleanup();
            if (succ)
            {
                bInit = false;
            }
            
       

                return succ;
        }

        public void MsgCallback(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            //通过lCommand来判断接收到的报警信息类型，不同的lCommand对应不同的pAlarmInfo内容
            switch (lCommand)
            {
                case CHCNetSDK.COMM_UPLOAD_PLATE_RESULT://交通抓拍结果上传(老报警信息类型)
                    ProcessCommAlarm_Plate(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CHCNetSDK.COMM_ITS_PLATE_RESULT://交通抓拍结果上传(新报警信息类型)
                    ProcessCommAlarm_ITSPlate(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 新报警信息类型
        /// </summary>
        /// <param name="pAlarmer"></param>
        /// <param name="pAlarmInfo"></param>
        /// <param name="dwBufLen"></param>
        /// <param name="pUser"></param>
        private void ProcessCommAlarm_ITSPlate(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            CHCNetSDK.NET_ITS_PLATE_RESULT struITSPlateResult = new CHCNetSDK.NET_ITS_PLATE_RESULT();
            uint dwSize = (uint)Marshal.SizeOf(struITSPlateResult);

            struITSPlateResult = (CHCNetSDK.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_ITS_PLATE_RESULT));

            //报警设备IP地址
            string strIP = pAlarmer.sDeviceIP;

            string lineNum = GetLineNumByIp(strIP);

            string strHPHM = struITSPlateResult.struPlateInfo.sLicense;
            string strHPZL = string.Empty;

            if (string.IsNullOrEmpty(strHPHM) == false)
            {
                if (strHPHM != "无车牌")
                {
                    strHPZL = GetHPZL(strHPHM);
                    strHPHM = strHPHM.Substring(1, strHPHM.Length - 1);
                }
                else
                {
                    strHPHM = string.Empty;
                }
            }
            m_fleck = Flecks.GetInstance();

            //向页面发送消息
            if (m_fleck != null)
            {
                 CONST_DEFINE_WEB_BLL bll = new CONST_DEFINE_WEB_BLL();
                 CONST_DEFINE_WEB entity  =bll.GetModel(38);

                string QY = string.Empty;
                string HM = string.Empty;
                if (strHPHM != string.Empty)
                {
                    QY = strHPHM.Substring(0, 1); //车牌区域代号部分
                    HM = strHPHM.Substring(1);   //车牌号码部分
                }
                m_fleck.SendMsg(@"{'Mark':'AJLogin','Msg':[{HM:'" + HM + "',QY:'" + QY + "',IP:'" + strIP + "',ZL:'" + strHPZL + "',LN:'" + lineNum + "',isOnline:'"+entity.Code+"'}]}");

            }
        }

        /// <summary>
        /// 获取号牌种类
        /// </summary>
        /// <param name="strHPHM">获取的车牌号码</param>
        /// <returns></returns>
        private string GetHPZL(string strHPHM)
        {
            string zlStr = string.Empty;

            string colorStr = strHPHM.Substring(0, 1);  //截取代表颜色的文字
            switch (colorStr)
            {
                case "蓝":
                    zlStr = "02";
                    break;
                case "黄":
                    if (strHPHM.Contains("学"))
                    {
                        zlStr = "16";
                    }
                    else
                    {
                        zlStr = "01";
                    }
                    break;
                case "白":
                    zlStr = "23";
                    break;
                case "黑":
                    zlStr = "03";
                    break;
                default:
                    zlStr = "00";
                    break;
            }


            return zlStr;
        }

        private void ProcessCommAlarm_Plate(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            CHCNetSDK.NET_ITS_PLATE_RESULT struITSPlateResult = new CHCNetSDK.NET_ITS_PLATE_RESULT();
            uint dwSize = (uint)Marshal.SizeOf(struITSPlateResult);

            struITSPlateResult = (CHCNetSDK.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_ITS_PLATE_RESULT));

            //报警设备IP地址
            string strIP = pAlarmer.sDeviceIP;
            string lineNum = GetLineNumByIp(strIP);

            //上传结果
            //string stringAlarm = "抓拍上传，" + "车牌：" + struITSPlateResult.struPlateInfo.sLicense + "，车辆序号：" + struITSPlateResult.struVehicleInfo.dwIndex;

            byte b = struITSPlateResult.struPlateInfo.byColor;

            string strHPHM = struITSPlateResult.struPlateInfo.sLicense;


            string strHPZL = GetHPZL(Convert.ToInt32(b), strHPHM);


        }

        private string GetHPZL(int iType, string strHPHM)
        {
            string strType = "";
            switch (iType)
            {
                case 0://蓝牌
                    strType = "02";//小型汽车
                    break;
                case 1://黄牌
                    if (strHPHM.Contains("学"))
                    {//教练车
                        strType = "16";
                    }
                    else
                    {//大型汽车
                        strType = "01";
                    }
                    break;
                case 2://白牌
                    strType = "23";//警用车辆
                    break;
                case 3://黑牌
                    strType = "03";//外籍使馆车
                    break;
                default:
                    strType = "02";
                    break;
            }

            return strType;
        }



        /// <summary>
        /// 根据IP地址获取线号
        /// </summary>
        /// <param name="ipAdress">IP地址</param>
        private string GetLineNumByIp(string ipAdress)
        {
            string lineNum = string.Empty;
            CAMERA_INFO_BLL bll = new CAMERA_INFO_BLL();
            var Infos = bll.GetModelList("IsEnabled='True' and CameraIP='" + ipAdress + "'");
            if (Infos.Length > 0)
            {
                lineNum = Infos[0].LineNum;
            }
            return lineNum == string.Empty ? "0" : lineNum;
        }

    }


}
